// 使用rudux-toolkit来实现reducer
// 2. 引入createSlice 返回reducer
import { createSlice, PayloadAction, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

// 1.定义state
interface ShoppingCartState {
  items: any[]; // 是一个数组
  loading: boolean; // 请求状态
  error: string | null; // 错误信息
}

const defaultState: ShoppingCartState = {
  items: [],
  loading: true,
  error: null,
};

// ! 使用 createAsyncThunk api来实现异步的action 但是要使用redux-toolkit的configureStore
/**
 * @params1 命名空间
 * @params2 异步函数
 */
export const getShoppingCart = createAsyncThunk(
  "shoppingCart/getShoppingCart",
  async (jwt: string) => {
    // thunkAPI
    // thunkAPI.dispatch(productDetailSlice.actions.fetchStart());
    // try {
    //   const { data } = await axios.get(
    //     `http://123.56.149.216:8080/api/touristRoutes/${touristRouteId}`
    //   );
    //   thunkAPI.dispatch(productDetailSlice.actions.fetchSuccess(data));
    // } catch (error) {
    //   thunkAPI.dispatch(productDetailSlice.actions.fetchFail(error.message));
    // }

    // ! 使用createAsyncThunk的返回值 promise三种状态
    const { data } = await axios.get("http://123.56.149.216:8080/api/shoppingCart/", {
      headers: {
        Authorization: `bearer ${jwt}`, // 要使用bearer 开头
      },
    });
    return data.shoppingCartItems;
  }
);

/** 加入购物车 */
export const addShoppingCartItem = createAsyncThunk(
  "shoppingCart/addShoppingCartItem",
  async (params: { jwt: string; touristRouteId: string }) => {
    // ! 使用createAsyncThunk的返回值 promise三种状态
    const { data } = await axios.post(
      "http://123.56.149.216:8080/api/shoppingCart/items",
      {
        touristRouteId: params.touristRouteId,
      },
      {
        headers: {
          Authorization: `bearer ${params.jwt}`, // 要使用bearer 开头
        },
      }
    );
    return data.shoppingCartItems;
  }
);

/** 清空购物车 */
export const clearShoppingCartItem = createAsyncThunk(
  "shoppingCart/clearShoppingCartItem",
  async (params: { jwt: string; itemIds: number[] }) => {
    // ! 使用createAsyncThunk的返回值 promise三种状态
    return await axios.delete(
      `http://123.56.149.216:8080/api/shoppingCart/items/(${params.itemIds.join(",")})`,
      {
        headers: {
          Authorization: `bearer ${params.jwt}`, // 要使用bearer 开头
        },
      }
    );
  }
);

/** 购物车下单 */
export const checkout = createAsyncThunk("shoppingCart/checkout", async (jwt: string) => {
  // ! 使用createAsyncThunk的返回值 promise三种状态
  const { data } = await axios.post("http://123.56.149.216:8080/api/shoppingCart/checkout", null, {
    headers: {
      Authorization: `bearer ${jwt}`, // 要使用bearer 开头
    },
  });
  return data;// 返回新订单的数据
});

export const shoppingCartSlice = createSlice({
  name: "shoppingCart", // 命名空间
  initialState: defaultState, //初始化数据
  reducers: {
    fetchStart: (state) => {
      // return { ...state, loading: true };// !return 这是react的写法 state是immutable不可以修改的
      state.loading = true; // immer框架 内部的produce实现返回了一个新的object
    },
    fetchSuccess: (state, action) => {
      state.loading = false;
      state.items = action.payload; // 直接用action返回的数据来更新状态
      state.error = null;
    },
    fetchFail: (state, action: PayloadAction<string | null>) => {
      state.loading = false;
      state.error = action.payload;
    },
  },
  extraReducers: {
    // ! 使用createAsyncThunk的返回值 promise三种状态 必须使用extraReducers
    // 使用的是类型
    [getShoppingCart.pending.type]: (state) => {
      // return { ...state, loading: true };// !return 这是react的写法 state是immutable不可以修改的
      state.loading = true; // immer框架 内部的produce实现返回了一个新的object
    },
    [getShoppingCart.fulfilled.type]: (state, action) => {
      state.loading = false;
      state.items = action.payload; // 直接用payload传参来更新状态
      state.error = null;
    },
    [getShoppingCart.rejected.type]: (state, action: PayloadAction<string | null>) => {
      state.loading = false;
      state.error = action.payload;
    },
    [addShoppingCartItem.pending.type]: (state) => {
      // return { ...state, loading: true };// !return 这是react的写法 state是immutable不可以修改的
      state.loading = true; // immer框架 内部的produce实现返回了一个新的object
    },
    [addShoppingCartItem.fulfilled.type]: (state, action) => {
      state.loading = false;
      state.items = action.payload; // 直接用payload传参来更新状态
      state.error = null;
    },
    [addShoppingCartItem.rejected.type]: (state, action: PayloadAction<string | null>) => {
      state.loading = false;
      state.error = action.payload;
    },
    [clearShoppingCartItem.pending.type]: (state) => {
      // return { ...state, loading: true };// !return 这是react的写法 state是immutable不可以修改的
      state.loading = true; // immer框架 内部的produce实现返回了一个新的object
    },
    [clearShoppingCartItem.fulfilled.type]: (state) => {
      state.loading = false;
      state.items = []; // 清空购物车 变成空数组
      state.error = null;
    },
    [clearShoppingCartItem.rejected.type]: (state, action: PayloadAction<string | null>) => {
      state.loading = false;
      state.error = action.payload;
    },
    [checkout.pending.type]: (state) => {
      // return { ...state, loading: true };// !return 这是react的写法 state是immutable不可以修改的
      state.loading = true; // immer框架 内部的produce实现返回了一个新的object
    },
    [checkout.fulfilled.type]: (state) => {
      state.loading = false;
      state.items = []; // 购物车列表值为空数组
      //! 返回回来当前购物车数据直接在其他的slice进行调用action 进行数据绑定
      state.error = null;
    },
    [checkout.rejected.type]: (state, action: PayloadAction<string | null>) => {
      state.loading = false;
      state.error = action.payload;
    },
  },
});
